import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


public class TestArrayList {

    /**
     * ArrayList
     *
     * 添加add
     * 	1> 底层是一个Object的动态数组
     * 	2> 默认创建对象的时候会创建一个空的数组
     * 	3> 当添加第一个元素的时候,会给这个数组初始化10个位置的空间
     * 	4> 当数组存放满了的时候,会将数组进行扩容,扩成原数组的1.5倍
     * 	5> 然后继续添加,可以添加null
     *
     * 删除remove
     * 	1> 根据数组下标删除,假设要删除下标为n的元素
     * 		1.首先取出要删除位置n的元素
     * 		2.将n+1到最后一个元素整体往前移动一位,对n位置的值进行覆盖
     * 		3.返回被删除的n位置的元素
     *
     * 	2> 根据元素进行删除,假设要删除的元素为str
     * 		1.遍历数组,查找这个元素是否存在于数组中
     * 		2.如果不存在,返回一个false
     * 		3.如果存在,假设这个元素的下标为n
     * 		4.将n+1到最后一个元素整体往前移动一位,对n位置的值进行覆盖
     * 		5.返回true
     *
     */

    public static void main(String[] args) {

        //List list = new ArrayList();

        ArrayListTest list = new ArrayListTest();

        //添加4个元素
        for(int i = 0; i < 4; i++){
            list.add("胡琦"+ i);
        }
        list.print();

        //添加一个null
        list.add(null);

        //再添加7个元素,数组将进行扩容
        for(int i = 5; i < 11; i++){
            list.add("胡琦"+ i);
        }
        list.print();


        //删除指定位置的元素
        System.out.println("删除的元素是 : " + list.remove(2));
        list.print();


        //删除指定位置的元素,错误下标
        System.out.println("删除的元素是 : " + list.remove(10));
        list.print();


        //删除指定元素,删除不存在的元素
        System.out.println("删除元素是否成功 : " + list.remove("胡琦2"));
        list.print();

        //删除指定元素
        System.out.println("删除元素是否成功 : " + list.remove("胡琦4"));
        list.print();

        //删除指定元素,删除null
        System.out.println("删除元素是否成功 : " + list.remove(null));
        list.print();

    }

}

class ArrayListTest{

    //创建对象时创建一个Object空数组
    private Object[] arrs;

    //最小容量,最近放入的元素的下一个位置下标,当前数组的元素个数
    private int index = 0;


    //向集合中添加元素
    public void add(Object obj){

        //判断是否是首次放入元素
        //是的话将数组初始化10个长度
        if(index == 0){
            arrs = new Object[10];
        }

        //判断数组的容量是否满了
        if(index == arrs.length){//数组元素个数和数组长度相同

            //如果已经存放满了.就对数组进行扩容
            //容量是原来数组的1.5倍
            //arrs = Arrays.copyOf(arrs, (arrs.length + arrs.length >> 1));
            arrs = Arrays.copyOf(arrs, (int)(arrs.length * 1.5));
            System.out.println("集合进行了扩容...");
        }

        //将元素放入数组中
        //arrs[index++] = obj;
        arrs[index] = obj;
        index++;
    }


    //根据元素下标删除元素
    public Object remove(int n){

        //System.out.println("index = " + index);
        //检查输入的下标位置是否正确
        if(!(n >= 0 && n < index)){
            System.out.println("输入有误");
            return "删除失败";
        }else{

            Object obj = arrs[n];//获取删除的元素

            //将要删除的位置的元素后面的元素整体往前移动一个位置
            move(n);

            //删除成功一个元素,将index减一
            index--;
            return obj;
        }
    }


    //根据元素的内容删除元素
    public boolean remove(Object obj){

        //看是否是空元素
        //如果是空元素就直接删除覆盖
        if(obj == null){

            for(int i = 0; i < arrs.length; i++){

                //找到了第一个空
                if(arrs[i] == null){

                    //将要删除的位置的元素后面的元素整体往前移动一个位置
                    move(i);
                    index--;
                    return true;
                }
            }

        }else{
            for(int i = 0; i < arrs.length; i++){

                //防止空指针异常
                if(arrs[i] == null){
                    return false;
                }

                //如果这个元素在集合中存在就进行删除
                if(arrs[i].equals(obj)){

                    //将要删除的位置的元素后面的元素整体往前移动一个位置
                    move(i);

                    index--;
                    return true;
                }
            }
        }

        return false;
    }

    //移动元素
    private void move(int i){//i为要覆盖的元素的下标

        //集合中要删除的元素后面的元素个数
        int n = arrs.length - i - 1;

        //判断这个元素是不是最后一个元素
        if(n > 0){
            //复制要删除的元素的后面的所有元素
            //原数组--从元素组的i+1位置开始复制--目标数组--从目标数组的i位置开始复制--要复制的元素个数
            //即将数组的i+1到最后一个元素复制到新数组的i到最后一个元素,将原本i位置的元素进行覆盖
            System.arraycopy(arrs, i+1, arrs, i, n);

        }else{
            arrs[i] = null;
        }
    }


    //打印集合
    public void print(){

        //遍历数组中包含的元素
        for(int i = 0; i < index; i++){
            System.out.print(arrs[i] + "  ");
        }

        System.out.println();
        System.out.println("集合含有的元素个数为: " + index);
        System.out.println("数组当前长度为 : " + arrs.length);
        System.out.println("-----------------------------");
    }

}
